package com.wuliang.generate.common.core.adapter.json;

import com.google.gson.TypeAdapter;
import com.google.gson.internal.LinkedTreeMap;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 阿里 Gson 转化工具中，会对字符串中的 int 类型数据转成 double 类型
 * 故此重写转换方法
 *
 * @author 邬魉
 */
public class GsonTypeAdapter extends TypeAdapter {

    private static final String NTH_POWER_OF_TEN = "E";

    @Override
    public void write(JsonWriter out, Object value) throws IOException {
    }

    @Override
    public Object read(JsonReader in) throws IOException {
        JsonToken jsonToken = in.peek();
        switch (jsonToken) {
            case BEGIN_ARRAY:
                List<Object> list = new ArrayList<Object>();
                in.beginArray();
                while (in.hasNext()) {
                    list.add(read(in));
                }
                in.endArray();
                return list;
            case BEGIN_OBJECT:
                Map<String, Object> map = new LinkedTreeMap<String, Object>();
                in.beginObject();
                while (in.hasNext()) {
                    map.put(in.nextName(), read(in));
                }
                in.endObject();
                return map;
            case STRING:
                return in.nextString();
            case NUMBER:
                Double number = in.nextDouble();
                String s = String.valueOf(number);
                String s1 = s.substring(s.indexOf(".") + 1);
                if (s.contains(NTH_POWER_OF_TEN)) {
                    return number;
                }
                if (Integer.parseInt(s1) != 0) {
                    return number;
                }
                return ((int) Double.parseDouble(s));
            case BOOLEAN:
                return in.nextBoolean();
            case NULL:
                in.nextNull();
                return null;
            default:
                throw new IllegalStateException();
        }

    }
}
